正则表达式语法
正则表达式是由普通字符(例如数字、字母、标点和用来表示特定字符或字符集的元字符)以及特殊字符(用作限定条件或特殊功能的字符)组成的文字模式。
普通字符
所有数字、小写字母、大写字母、标点都属于普通字符。
而为了匹配除以上列出的字符集以外的字符,或者匹配特定范围内的任意字符,需要使用元字符。元字符分直接量字符和字符类。
直接量字符
字符 | 描述 |
---|---|
uXXXX | 由16进制数XXXX指定的unicode字符 |
xNN | 由16进制数NN指定的拉丁字符 |
o | NUL字符(u0000) |
t | 制表符(u0009) |
n | 换行符(u000A) |
v | 垂直制表符(u000B) |
f | 换页符(u000C) |
r | 回车符(u000D) |
字符类元字符
字符类元字符用来匹配特定范围内的字符。一个字符类可以匹配它所包含的任意字符。
字符 | 描述 |
---|---|
. | 除了换行和行结束符之外的所有单个字符 |
w | 等价于[0-9a-zA-Z] |
W | 除了w以外的所有字符 |
s | 任何Unicode空白符 |
S | 任何非Unicode空白符的字符(范围比w大) |
d | 等价于[0-9] |
D | 除了d以外的所有字符 |
[...] | 方括号内的任意字符 |
1 | 除了方括号内字符集的任意字符 |
特殊字符
重复
当需要匹配多个指定的字符时,需要用到一些专门的特殊字符来表示重复匹配的次数。
字符 | 描述 |
---|---|
{n,m} | 匹配至少n次,但不能超过m次 |
{n,} | 匹配至少n次,无上限 |
{n} | 匹配n次 |
? | 匹配0次或1次,等价于{0,1} |
+ | 匹配1次或多次,无上限,等价于{1,} |
* | 匹配0次或多次,无上限,等价于{0,} |
重复字符需要与普通字符配合使用,如[a-z]{3,5},即匹配3个到5个小写字母。
锚字符
当需要匹配以指定字符开头或结尾的字符串时,需要用到锚字符。
字符 | 描述 |
---|---|
^ | 匹配字符串的开头,在多行检索中,匹配一行的开头 |
$ | 匹配字符串的结尾,在多行检索中,匹配一行的结尾 |
(?=p) | 零宽正向先行断言,要求接下来的字符都与p匹配,匹配结果不包含p |
(?!p) | 零宽负向先行断言,要求接下来的字符不能和p匹配 |
b | 匹配一个字边界(需要和其他表达式配合使用,单独使用[b]表示退格符) |
B | 匹配一个非字边界 |
例:需要匹配以字母、下划线或$开头的字符串来校验变量名是否合法,可以使用/^[a-zA-Z_$].*/
注:^在方括号[]内部表示反向匹配。
零宽先行断言可以将任何正则表达式都做为结尾锚点,q(?=p)表示匹配所有以p结尾的q字符串,匹配结果仅包含q部分,不包含锚点p。
例:匹配以”.”结尾的字符串,可以使用/w+(?=.)/g
则匹配'a.b.c.d.e.f'的结果为['a','b','c','d','e']。f后没有.,所以不被匹配。
q(?!p)表示匹配所有不以p结尾的q字符串。
注:javascript不支持后行断言,即不能将正则表达式作为开始锚点。
b可以用来匹配一个单词的开头或结尾。例:匹配String中的Str用/bStr/,匹配String中的ing用/ingb/
B可用来匹配一个单词的中间部分。例:匹配String中的trin用/BtrinB/
选择、分组和引用字符
字符 | 描述 |
---|---|
| | 选择匹配,“|”左边的表达式和右边的表达式皆可匹配 |
(...) | 分组匹配,将几个项组合为一个单元,这个单元可以用"*","+","?","|","{n,m}"等符号加以修饰。而且可以记住和这个组合相匹配的字符。 |
(?:...) | 非捕获性分组,只负责匹配,不记忆与该组相匹配的字符 |
(?:...)和(...)的差异仅仅存在与匹配结果,当需要记录某一部分匹配项时,用(...)。若只是用来匹配,后续不需要使用分组匹配到的字符串,则用(?:...)
转义字符
字符 | 描述 |
---|---|
\ |
RegExp使用
RegExp实例化方法
RegExp实例化有两张方式。一种通过字面量实例化,一种通过new RegExp()构造函数实例化
var exp = / pattern / flags; //RegExp字面量
var exp = new RegExp("pattern","flags"); //RegExp构造函数
flags用来表示正则表达式的行为。可选项有g,i,m三个标识,可同时定义一个或多个标识。
g:global,表示全局模式。flags中包含g时,表达式匹配所有能够匹配上的字符串;如果没包含g时,则当匹配到第一个字符串时,即停止匹配。
i:case-insentive,表示忽略大小写。flags中包含i时,表达式匹配时忽略字符串的大小写。
m:multi-line,表示多行匹配。flags中包含m时,表达式匹配到一行文本末尾时还会继续查找下一行中是否存在匹配项。
pattern即正则表达式语句。
RegExp构造函数优势在于可以动态传入正则表达式。
RegExp实例属性
global
boolean值,表示是否设置了g标志。
ignoreCase
boolean值,表示是否设置了i标志。
multiline
boolean值,表示是否设置了m标志。
source
正则表达式的字符串表示,按照字面量形式而非传入构造函数中的字符串模式返回。
lastIndex
整数,表示开始搜索下一个匹配项的字符位置,从0 算起。
例:
var exp = /\[bc\]at/gi;
exp.global;//true
exp.ignoreCase;//true
exp.multiline;//false
exp.source;//“\[bc\]at”
RegExp实例方法
exec()
exec方法接受一个参数,即需要应用模式的字符串,然后返回包含第一个匹配项信息的数组,或者在没有匹配项时返回null。返回的数组是Array实例,但还包含额外两个属性:index和input。
一句句解释。
返回包含第一个匹配项信息的数组,或者在没有匹配项时返回null:
这里分两种情况,一种是global匹配,一种是非global匹配。
global模式执行exec()匹配成功一次以后,再次执行exec()时,会从前一次匹配的最后一位开始继续向后匹配。例:
var exp = /.at/g
var matches = exp.exec('cat, bat, sat, fat'); //第一次匹配
matches.index => 0
matches.input => 'cat, bat, sat, fat'
matches => ['cat']
exp.lastIndex => 3
matches = exp.exec('cat, bat, sat, fat'); //第二次匹配
matches.index => 5
matches.input => 'cat, bat, sat, fat'
matches => ['bat']
exp.lastIndex => 8
...
非global模式执行exec()匹配成功一次以后,再次执行exec()时,会从头开始重新匹配。
var exp = /.at/
var matches = exp.exec('cat, bat, sat, fat'); //第一次匹配
matches.index => 0
matches.input => 'cat, bat, sat, fat'
matches => ['cat']
exp.lastIndex => 0
matches = exp.exec('cat, bat, sat, fat'); //第二次匹配
matches.index => 0
matches.input => 'cat, bat, sat, fat'
matches => ['cat']
exp.lastIndex => 0
返回的数组是Array实例:
当使用(...)分组匹配时,一次exec()会匹配到多个结果
var exp = /(there)\s+(you)\s+(are)/;
var matches = exp.exec('hey, there you are my dear');
matches = ["there you are", "there", "you", "are"];
matches[0]匹配整个表达式字符串。
matches[1]匹配第一个(...)内的字符串,之后以此类推。
补充说明:含(?:...)非捕获分组的表达式执行exec后返回的数组中不包含(?:...)匹配的字符串。非捕获性分组(?:...)和捕获性分组(...)的区别就在这里。
属性index和input:
index表示匹配项在字符串中的起始位置。
input表示应用正则表达式的字符串。
test()
test方法接受一个参数作为需要应用模式的字符串,在模式与该参数匹配的情况下返回true,否则返回false。在只想知道目标字符串与某个模式是否匹配,但不需要知道其文本内容的情况下,使用这个方法非常方便。因此,test()方法经常被用在if 语句中。
用于模式匹配的string方法
string有四个方法可以将正则表达式作为参数传入。
search()
str.search(exp)返回str中第一个与exp表达式匹配的字符串的起始位置。如果找不到匹配项,返回-1。如果search传入的参数是一个string,则首先会通过RegExp构造函数将其转换为正则表达式。search不支持全局搜索,它会忽略global标识。
'JavaScript'.search(/script/i) => 4
replace()
str.replace(exp, replaceStr)第一个参数是一个正则表达式,第二个参数是要替换成的字符串。如果exp带有global标识,那么源字符str中所有与exp表达式匹配的子串都会被替换。如果不带g,str中仅第一个与exp匹配的子串会被替换。
text.replace(/javascript/gi, 'JS') //将text全文中所有javascript改为JS
replaceStr中如果出现$加数字N的字符串,表示第N个子表达式相匹配的文本。
text.replace(/'([^']*)'/g, '"$1"') //将text全文中所有被''引用的子串替换成被""引用。
match()
str.match(exp)返回一个由匹配结果组成的数组。
该数组不同于RegExp实例方法exex()返回的数组。当有global标识时,match返回全局匹配到的所有字符串组成的数组;当没有global标识时,match就返回第一个匹配到的字符串组成的单元素数组。
'11+2=13'.match(/\d/g) => ['1','1','2','1','3']
'11+2=13'.match(/\d/) => ['1']
match方法不会返回捕获性组合匹配到的子串,(...)分组匹配在match方法中不会像RegExp实例方法exec()一样返回匹配的子串。
split()
当split方法传入的参数为正则表达式时,这使得split()方法异常强大。例如,可以指定分隔符,允许两边可以留有任意多的空白符:
'1 , ,2 , 3 , 4 , 5'.split(/\s*,\s*/) => ['1','2','3','4','5']
- ... ↩
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。